import {
  BadRequestException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { paymentMethods } from '../config/payment-methods.config';
import { Payment, PaymentMethodType } from '../entities/payment.entity';
import { OrdersService } from '../orders/orders.service';
import { CreatePaymentDto } from './dto/create-payment.dto';
import { UpdatePaymentDto } from './dto/update-payment.dto';

@Injectable()
export class PaymentsService {
  constructor(
    @InjectRepository(Payment)
    private paymentsRepository: Repository<Payment>,
    private ordersService: OrdersService,
  ) {
    // 禁用自动初始化模拟数据，避免外键约束错误
    // 开发环境可以通过API手动添加数据
  }

  // 检查支付方式是否可用
  private checkPaymentMethodEnabled(method: PaymentMethodType): boolean {
    const paymentMethod = paymentMethods.find((pm) => pm.name === method);
    return paymentMethod ? paymentMethod.enabled : false;
  }

  // 获取所有可用的支付方式
  getAvailablePaymentMethods() {
    return paymentMethods.filter((method) => method.enabled);
  }

  async findAll(): Promise<Payment[]> {
    return this.paymentsRepository.find({
      relations: ['order'],
    });
  }

  async findOne(id: number): Promise<Payment> {
    const payment = await this.paymentsRepository.findOne({
      where: { paymentID: id },
      relations: ['order'],
    });

    if (!payment) {
      throw new NotFoundException(`未找到ID为${id}的支付记录`);
    }

    return payment;
  }

  async findByOrder(orderId: number): Promise<Payment[]> {
    return this.paymentsRepository.find({
      where: { orderID: orderId },
    });
  }

  async create(createPaymentDto: CreatePaymentDto): Promise<Payment> {
    // 验证订单是否存在
    await this.ordersService.findOne(createPaymentDto.orderID);

    // 验证支付方式是否可用
    const method = createPaymentDto.paymentMethod || '线下到店支付';
    if (!this.checkPaymentMethodEnabled(method)) {
      throw new BadRequestException(
        `支付方式 ${method} 当前不可用，请选择线下到店支付`,
      );
    }

    const newPayment = this.paymentsRepository.create(createPaymentDto);
    return this.paymentsRepository.save(newPayment);
  }

  async update(
    id: number,
    updatePaymentDto: UpdatePaymentDto,
  ): Promise<Payment> {
    const payment = await this.findOne(id);

    // 如果修改了订单ID，验证新订单是否存在
    if (
      updatePaymentDto.orderID &&
      updatePaymentDto.orderID !== payment.orderID
    ) {
      await this.ordersService.findOne(updatePaymentDto.orderID);
    }

    // 如果修改了支付方式，验证支付方式是否可用
    if (updatePaymentDto.paymentMethod) {
      if (!this.checkPaymentMethodEnabled(updatePaymentDto.paymentMethod)) {
        throw new BadRequestException(
          `支付方式 ${updatePaymentDto.paymentMethod} 当前不可用，请选择线下到店支付`,
        );
      }
    }

    Object.assign(payment, updatePaymentDto);
    return this.paymentsRepository.save(payment);
  }

  async markAsPaid(id: number): Promise<Payment> {
    const payment = await this.findOne(id);
    payment.isPaid = true;
    return this.paymentsRepository.save(payment);
  }

  async remove(id: number): Promise<void> {
    const result = await this.paymentsRepository.delete(id);

    if (result.affected === 0) {
      throw new NotFoundException(`未找到ID为${id}的支付记录`);
    }
  }
}
